// DesktopOrganizer.cpp
#include "DesktopOrganizer.h"
#include <QProcess>
#include <QDir>
#include <QStandardPaths>

#ifdef Q_OS_WIN
#include <windows.h>
#include <shellapi.h>
#endif

DesktopOrganizer::DesktopOrganizer(QWidget* parent) : QMainWindow(parent) {}

bool DesktopOrganizer::organizeDesktop(OrganizeMode mode) {
#if defined(Q_OS_WIN)
    return organizeWindows(mode);
#elif defined(Q_OS_LINUX)
    return organizeLinux(mode);
#elif defined(Q_OS_MACOS)
    return organizeMacOS(mode);
#else
    return false;
#endif
}

bool DesktopOrganizer::isDesktopOrganizable() {
    // 检查是否有桌面操作权限
    QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QDir desktopDir(desktopPath);
    return desktopDir.exists() && desktopDir.isReadable();
}

/// <summary>
/// 方法二
/// </summary>
/// <param name="arrangementType"></param>
void DesktopOrganizer:: arrangeDesktopIcons(int arrangementType) {
    // 获取桌面列表视图句柄
    HWND hDesktop = ::FindWindow(L"Progman", L"Program Manager");
    HWND hShellView = ::FindWindowEx(hDesktop, NULL, L"SHELLDLL_DefView", NULL);
    HWND hListView = ::FindWindowEx(hShellView, NULL, L"SysListView32", NULL);

    if (hListView == NULL) {
        // 有时需要尝试其他路径获取句柄
        hListView = ::FindWindow(L"Progman", L"Program Manager");
        hListView = ::FindWindowEx(hListView, NULL, L"SHELLDLL_DefView", NULL);
        hListView = ::FindWindowEx(hListView, NULL, L"SysListView32", NULL);
    }

    if (hListView != NULL) {
        UINT message = 0;
        WPARAM wParam = 0;
        LPARAM lParam = 0;

        // 根据整理类型选择消息，这些ID在Win11中可能需要验证或调整
        switch (arrangementType) {
        case 0: // 自动排列
            message = WM_COMMAND;
            wParam = 0x7029; // 自动排列图标命令
            break;
        case 1: // 对齐到网格
            message = WM_COMMAND;
            wParam = 0x7028; // 对齐图标到网格命令
            break;
        }

        if (message != 0) {
            // 发送消息
            LRESULT result = ::SendMessage(hListView, message, wParam, lParam);
            // 可以检查result处理错误
        }

        // 刷新桌面
        ::InvalidateRect(hListView, NULL, TRUE);
        ::UpdateWindow(hListView);
    }
}

#ifdef Q_OS_WIN
bool DesktopOrganizer::organizeWindows(OrganizeMode mode) {
    HWND hDesktop = FindWindow(L"Progman", L"Program Manager");
    if (!hDesktop) return false;

    switch (mode) {
    case AutoArrange:
        SendMessage(hDesktop, WM_COMMAND, 0x7029, 0); // 自动排列
        break;
    case AlignToGrid:
        SendMessage(hDesktop, WM_COMMAND, 0x7028, 0); // 对齐到网格
        break;
    default:
        SendMessage(hDesktop, WM_COMMAND, 0x7029, 0);
        break;
    }
	
    // 刷新桌面
    HWND hDesktopListView = FindWindowEx(hDesktop, NULL, L"SysListView32", NULL);
    if (hDesktopListView) {
        InvalidateRect(hDesktopListView, NULL, TRUE);
        UpdateWindow(hDesktopListView);
    }

    return true;
}
#endif

#ifdef Q_OS_LINUX
bool DesktopOrganizer::organizeLinux(OrganizeMode mode) {
    // 对于 GNOME 桌面环境
    QProcess process;

    switch (mode) {
    case AutoArrange:
        process.start("gsettings", { "set", "org.gnome.nautilus.desktop", "auto-arrange", "true" });
        break;
    case AlignToGrid:
        process.start("gsettings", { "set", "org.gnome.nautilus.desktop", "auto-arrange", "false" });
        process.start("gsettings", { "set", "org.gnome.nautilus.desktop", "sort-order", "'name'" });
        break;
    default:
        break;
    }

    return process.waitForFinished();
}
#endif

#ifdef Q_OS_MACOS
bool DesktopOrganizer::organizeMacOS(OrganizeMode mode) {
    QProcess process;
    QStringList args;

    switch (mode) {
    case AutoArrange:
        // macOS 默认就是自动排列的
        break;
    case SortByName:
        args << "-e" << "tell application \"Finder\" to set desktop arrangement to sort by name";
        process.start("osascript", args);
        break;
    case SortByDate:
        args << "-e" << "tell application \"Finder\" to set desktop arrangement to sort by creation date";
        process.start("osascript", args);
        break;
    default:
        break;
    }

    return process.waitForFinished();
}
#endif